package cn.supermaster.management.common.utils;

import cn.supermaster.management.common.constant.Constants;
import cn.supermaster.management.common.constant.WebConstant;
import cn.supermaster.management.common.utils.http.HttpUtils;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;

/**
 * 获取地址类
 */
public class AddressUtils {

    private static final Logger logger = LoggerFactory.getLogger(AddressUtils.class);
    // 未知地址
    public static final String UNKNOWN = WebConstant.IP_UNKNOWN;

    /**
     * @Description: [根据IP地址获取Address详情]
     * <p></P>
     * @Title: getRealAddressByIP
     * @Author: Lance Ting
     * @Date: 2021-01-12
     * @Param: ip
     * @Return: java.lang.String
     */
    public static String getRealAddressByIP(String ip) {
        String address = UNKNOWN;
        try {
            // 内网不查询
            if (internalIPAddress(ip)) {
                return "内网IP";
            }
            // 获取互联网地址信息
            String params = String.format("ip=%s&json=true", ip);
            String result = HttpUtils.sendGet(WebConstant.IP_SEARCHER, params, Constants.GBK);
            if (TextUtils.isEmpty(result)) {
                logger.error("获取地理位置异常 {}", ip);
                return address;
            }
            // 解析IP地址信息
            logger.info("根据IP地址{}获取地理位置信息 {}", ip, result);
            JSONObject obj = JSONObject.parseObject(result);
            String region = obj.getString("pro");// 省份信息
            String city = obj.getString("city");// 城市
            address = String.format("%s %s", region, city);

        } catch (Exception e) {
            logger.error("获取地理位置异常 {}", e);
        }
        return address;
    }

    /**
     * @Description: [获取IP地址]
     * <p></P>
     * @Title: getIPAddress
     * @Author: Lance Ting
     * @Date: 2021-01-03
     * @Param: request
     * @Return: java.lang.String
     */
    public static String getIPAddress(HttpServletRequest request) {
        if (request == null) {
            return "unknown";
        }
        String ip = getIPAddressFromRequest(request, "x-forwarded-for");
        if (isNullOrUnknown(ip)) ip = getIPAddressFromRequest(request, "Proxy-Client-IP");
        if (isNullOrUnknown(ip)) ip = getIPAddressFromRequest(request, "X-Forwarded-For");
        if (isNullOrUnknown(ip)) ip = getIPAddressFromRequest(request, "WL-Proxy-Client-IP");
        if (isNullOrUnknown(ip)) ip = getIPAddressFromRequest(request, null);
        //
        return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
    }

    /**
     * @Description: [判断时是否是内网地址]
     * <p></P>
     * @Title: internalIp
     * @Author: Lance Ting
     * @Date: 2021-01-03
     * @Param: ip
     * @Return: boolean
     */
    public static boolean internalIPAddress(String ip) {
        byte[] addr = ConvertUtils.toNumericFormatV4(ip);
        return internalIPAddress(addr) || "127.0.0.1".equals(ip);
    }

    /**
     * @Description: [获取主机IP地址]
     * <p></P>
     * @Title: getHostIp
     * @Author: Lance Ting
     * @Date: 2021-01-03
     * @Return: java.lang.String
     */
    public static String getHostIp() {
        String host = "127.0.0.1";
        try {
            host = InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            logger.error("获取主机IP地址失败，" + e.getMessage());
        }
        return host;
    }

    /**
     * @Description: [获取主机名称]
     * <p></P>
     * @Title: getHostName
     * @Author: Lance Ting
     * @Date: 2021-01-03
     * @Return: java.lang.String
     */
    public static String getHostName() {
        String hastName = "未知";
        try {
            hastName = InetAddress.getLocalHost().getHostName();
        } catch (UnknownHostException e) {
            logger.error("获取主机名称失败，" + e.getMessage());
        }
        return hastName;
    }

    /**
     * @Description: [从Request中获取IP地址]
     * <p></P>
     * @Title: getIPAddressFromRequest
     * @Author: Lance Ting
     * @Date: 2021-01-03
     * @Param: ip IP地址
     * @Param: header request的header对象
     * @Return: java.lang.String
     */
    private static String getIPAddressFromRequest(HttpServletRequest request, String header) {
        return CheckUtils.isEmpty(header) ? request.getRemoteAddr() : request.getHeader(header);
    }

    /**
     * @Description: [内网地址判断]
     * <p></P>
     * @Title: internalIPAddress
     * @Author: Lance Ting
     * @Date: 2021-01-03
     * @Param: addr
     * @Return: boolean
     */
    private static boolean internalIPAddress(byte[] addr) {
        if (CheckUtils.isNull(addr) || addr.length < 2) {
            return true;
        }
        final byte b0 = addr[0];
        final byte b1 = addr[1];
        // 10.x.x.x/8
        final byte SECTION_1 = 0x0A;
        // 172.16.x.x/12
        final byte SECTION_2 = (byte) 0xAC;
        final byte SECTION_3 = (byte) 0x10;
        final byte SECTION_4 = (byte) 0x1F;
        // 192.168.x.x/16
        final byte SECTION_5 = (byte) 0xC0;
        final byte SECTION_6 = (byte) 0xA8;
        switch (b0) {
            case SECTION_1:
                return true;
            case SECTION_2:
                if (b1 >= SECTION_3 && b1 <= SECTION_4) return true;
            case SECTION_5:
                if (b1 == SECTION_6) return true;
            default:
                return false;
        }
    }

    /**
     * @Description: [IP地址是否空或未知]
     * <p></P>
     * @Title: isNullOrUnknown
     * @Author: Lance Ting
     * @Date: 2021-01-03
     * @Param: ip
     * @Return: boolean
     * @Throws:
     */
    private static boolean isNullOrUnknown(String ip) {
        return CheckUtils.isEmpty(ip) || "unknown".equalsIgnoreCase(ip);
    }
}
